package com.alan.product.issue.controller;

import com.alan.product.issue.entity.Order;
import com.alan.product.issue.exception.ParamErrorException;
import com.alan.product.issue.exception.ServerErrorException;
import com.alan.product.issue.entity.User;
import com.alan.product.issue.service.OrderService;
import com.alan.product.issue.threadpool.MySubThreadPool;
import com.alan.product.issue.threadpool.MyThreadPool;
import com.alan.product.issue.util.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.*;

@Slf4j
@RestController
@RequestMapping("order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    private static final ExecutorService THREAD_POOL = Executors.newFixedThreadPool(4);

    @PostMapping
    public String createOrder(@RequestBody Order order) {
        return orderService.createOrder(order);
    }

    @PostMapping("batch")
    public String batchCreateOrder(@RequestBody List<Order> orderList) {
        return orderService.batchCreateOrder(orderList);
    }

    @PostMapping("importOrder")
    public String importOrder(@RequestBody List<Long> dataList) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(dataList.size());

        log.info("outer user is [{}]", UserContext.getUser());

        for (Long data : dataList) {
            MyThreadPool.execute(()->{
                User user = UserContext.getUser();
                log.info("current user is [{}]", user);
                log.info("current data is [{}]", data);

                Future<Boolean> future = MySubThreadPool.submit(()->{
                    return remoteCall();
                });

                // do something else

                try {
                    Boolean remoteResult = future.get();
                } catch (Exception e) {
                    log.error("remote call error", e);
                }

                // do something else

                countDownLatch.countDown();
            });
        }

        countDownLatch.await();

        return "success";
    }

    private Boolean remoteCall() {
        log.info("remote call executed");
        return true;
    }

    @GetMapping("exceptionTest")
    public String exceptionTest(Integer a) {
        if (a == null) {
            // 这里是不需要打印日志的
            throw new ParamErrorException("a cannot be null");
        }
        return String.valueOf(a);
    }

    @GetMapping("exceptionTest2")
    public String exceptionTest2(Integer a, Integer b) {
        if (a == null || b == null) {
            throw new ParamErrorException("a and b cannot be null");
        }
        log.info("context is a=[{}], b=[{}]", a, b);
        try {
            return String.valueOf(a / b);
        } catch (Exception e) {
            throw new ServerErrorException("calculate error", e);
        }
    }

}
